#include <iostream>
#include <algorithm>

using ll = long long;

auto &is = std::cin;
auto &os = std::cout;

const ll max_n{300+5},max_m{8000+5};
struct Edge{
    ll u,v,c;
}edges[max_m];
ll n, m, u, v, c, edges_size;

template<ll size>
struct UnionSet{
    ll father[size];
    constexpr UnionSet()noexcept{
        for(ll i{0};i<size;i++){
            father[i]=i;
        }
    }
    constexpr ll find(const ll n)noexcept{
        if(father[n]==n)return n;
        return father[n]=find(father[n]);
    }
    constexpr void merge(const ll a,const ll b)noexcept{
        father[find(a)]=father[find(b)];
    }
    constexpr bool is_same(const ll a,const ll b)noexcept{
        return find(a)==find(b);
    }
};

UnionSet<max_n> u_set;
ll ans_num, ans_max;

int main(){
    is>>n>>m;

    for(ll i{0};i<m;i++){ // 注意题目条件
        is>>u>>v>>c;
        edges[edges_size++] = {u,v,c};
    }

    std::sort(edges,edges+edges_size,[](Edge &a,Edge &b)constexpr noexcept ->bool{
        return a.c<b.c;
    });

    for(ll i{0};i<edges_size;i++){
        if(!u_set.is_same(edges[i].u, edges[i].v)){
            u_set.merge(edges[i].u, edges[i].v);
            ans_num++;
            ans_max=edges[i].c;
        }
    }
    os<<ans_num<<' '<<ans_max<<'\n';
}

/*

4 5
1 2 3
1 4 5
2 4 7
2 3 6
3 4 8
*/